//===============================================================================================================
// System  : Sandcastle Help File Builder Utilities
// File    : MSHelpKeyword.cs
// Author  : Eric Woodruff  (Eric@EWoodruff.us)
// Updated : 06/05/2015
// Note    : Copyright 2008-2015, Eric Woodruff, All rights reserved
// Compiler: Microsoft Visual C#
//
// This file contains a class representing an Microsoft help index keyword that can be added to the XML data
// island in each help topic generated by BuildAssembler.
//
// This code is published under the Microsoft Public License (Ms-PL).  A copy of the license should be
// distributed with the code and can be found at the project website: https://GitHub.com/EWSoftware/SHFB.  This
// notice, the author's name, and all copyright notices must remain intact in all applications, documentation,
// and source files.
//
//    Date     Who  Comments
// ==============================================================================================================
// 03/25/2008  EFW  Created the code
// 12/18/2011  EFW  Updated for use with the new content editors
// 06/05/2015  EFW  Removed support for obsolete Help 2 index names
//===============================================================================================================

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Web;

namespace SandcastleBuilder.Utils
{
    /// <summary>
    /// This represents an Microsoft help index keyword that can be added to the XML data island in each help
    /// topic generated by BuildAssembler.
    /// </summary>
    public class MSHelpKeyword : IComparable<MSHelpKeyword>, INotifyPropertyChanged
    {
        #region Private data members
        //=====================================================================

        private static string[] validIndexNames = new[] { "K", "F" };

        private static Dictionary<string, string> indexNamesDataSource = new Dictionary<string, string>
        {
            { "K", "Keyword" },
            { "F", "F1 Help" }
        };

        private string index, term;
        #endregion

        #region Properties
        //=====================================================================

        /// <summary>
        /// This read-only property returns an enumerable list of valid index names
        /// </summary>
        public static IEnumerable<string> ValidIndexNames
        {
            get { return validIndexNames; }
        }

        /// <summary>
        /// This read-only property returns a dictionary containing the valid index names and their descriptions
        /// suitable for data binding.
        /// </summary>
        public static IDictionary<string, string> IndexNamesDataSource
        {
            get { return indexNamesDataSource; }
        }

        /// <summary>
        /// This is used to get or set the index name
        /// </summary>
        public string Index
        {
            get { return index; }
            set
            {
                if(value == null || value != index)
                {
                    if(String.IsNullOrWhiteSpace(value) || !ValidIndexNames.Contains(value))
                        index = "K";
                    else
                        index = value;

                    this.OnPropertyChanged();
                }
            }
        }

        /// <summary>
        /// This is used to get or set the index term
        /// </summary>
        public string Term
        {
            get { return term; }
            set
            {
                if(value != term)
                {
                    term = value;
                    this.OnPropertyChanged();
                }
            }
        }
        #endregion

        #region Constructors
        //=====================================================================

        /// <summary>
        /// Constructor
        /// </summary>
        /// <remarks>The index name defaults to "K"</remarks>
        public MSHelpKeyword() : this(null, null)
        {
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="indexName">The index name</param>
        /// <param name="keywordTerm">The index term</param>
        public MSHelpKeyword(string indexName, string keywordTerm)
        {
            this.Index = indexName;
            this.Term = keywordTerm;
        }
        #endregion

        #region IComparable<MSHelpKeyword> Members
        //=====================================================================

        /// <summary>
        /// Compares this instance to another instance and returns an indication of their relative values
        /// </summary>
        /// <param name="other">A MSHelpKeyword object to compare</param>
        /// <returns>Returns -1 if this instance is less than the value, 0 if they are equal, or 1 if this
        /// instance is greater than the value or the value is null.</returns>
        /// <remarks>Entries are sorted by name and then value</remarks>
        public int CompareTo(MSHelpKeyword other)
        {
            int result = 0;

            if(other == null)
                return 1;

            result = String.Compare(index, other.Index, StringComparison.Ordinal);

            if(result == 0)
                result = String.Compare(term, other.Term, StringComparison.CurrentCulture);

            return result;
        }
        #endregion

        #region INotifyPropertyChanged Members
        //=====================================================================

        /// <summary>
        /// The property changed event
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// This raises the <see cref="PropertyChanged"/> event
        /// </summary>
        /// <param name="propertyName">The property name that changed</param>
        protected void OnPropertyChanged([CallerMemberName]string propertyName = null)
        {
            var handler = PropertyChanged;

            if(handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion

        #region Equality, hash code, and To String
        //=====================================================================

        /// <inheritdoc />
        public override bool Equals(object obj)
        {
            MSHelpKeyword kw = obj as MSHelpKeyword;

            if(kw == null)
                return false;

            return (this == kw || (this.Index == kw.Index && this.Term == kw.Term));
        }

        /// <summary>
        /// Get a hash code for this item
        /// </summary>
        /// <returns>Returns the hash code for the index name and term</returns>
        public override int GetHashCode()
        {
            return this.ToString().GetHashCode();
        }

        /// <summary>
        /// Return a string representation of the item
        /// </summary>
        /// <returns>Returns the item in its XML format</returns>
        public override string ToString()
        {
            return String.Format(CultureInfo.InvariantCulture, "<MSHelp:Keyword Index=\"{0}\" Term=\"{1}\" />",
                index, HttpUtility.HtmlEncode(term));
        }
        #endregion
    }
}
